import java.util.Arrays;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: lishuo
 * Date: 2024-03-05
 * Time: 21:21
 */
public class DP {
    // 泰波那锲数列
    public int tribonacci(int n) {
        if (n == 0 || n == 1) {
            return n;
        }
        if (n == 2) {
            return 1;
        }
        // dp->动态规划
        int a = 0;
        int b = 1;
        int c = 1;
        int d = 0;
        for (int i = 3; i <= n; i ++) {
            d = a+b+c;
            a = b;
            b = c;
            c = d;
        }
        return d;
    }

    // 上台阶问题
    public int waysToStep(int n) {
        if (n == 1 || n == 2) {
            return n;
        }
        if (n == 3) {
            return 4;
        }
        int dp1 = 1;
        int dp2 = 2;
        int dp3 = 4;
        int dpi = 0;
        for (int i = 4; i <= n ; i ++) {
            // 两个相加就得去摸，否则溢出
            dpi = ((dp1 + dp2)%1000000007 + dp3)%1000000007;
            dp1 = dp2;
            dp2 = dp3;
            dp3 = dpi;
        }
        return dpi;
    }

    // 最小花费爬楼梯
    public int minCostClimbingStairs(int[] cost) {
        // 状态表示，i下标表示到达i位置的最小花费
        int[] dp = new int[cost.length+1];

        // 状态转移方程:dp[i] = min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2])
        // 初始化
        dp[0] = 0;
        dp[1] = 0;
        // 填表顺序:从左向右
        for (int i = 2; i < cost.length; i ++) {
            dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
        }
        return Math.min(dp[cost.length - 1] + cost[cost.length - 1], dp[cost.length - 2] + cost[cost.length - 2]);
    }


    // 解码个数
    public static int numDecodings(String s) {
        // 状态表示：dp[i]表示以i为结尾时，解码的方法总数

        // 状态转移方程：dp[i] = dp[i-1] + dp[i-2];

        // 初始化：dp[0] = 0|1   dp[1] = 0|1|2

        // 填表顺序：从左向右


        // 返回值：dp[n-1](n表示字符串长度)

        // 解题4步走：
        // 1.创建dp表 2.初始化 3.填表 4.返回值
        char[] ss = s.toCharArray();
        int[] dp = new int[s.length()];

        if (ss[0] != '0') dp[0] = 1; // 初始化第一个位置
        if (s.length() == 1) return dp[0]; // 处理边界情况

        if (ss[0] != '0' && ss[1] != '0') dp[1] += 1;
        int t = (ss[0] - '0')*10 + ss[1] - '0';
        if (t >= 10 && t <= 26) dp[1] += 1; // 初始化第二个位置

        // 填表
        for (int i = 2; i < s.length(); i ++) {
            // 先处理第一种情况
            if (ss[i] != '0') dp[i] += dp[i-1];
            // 处理第二种情况
            int tt = (ss[i-1] - '0')*10 + ss[i] - '0';
            if (tt >=10 && tt <= 26) dp[i] += dp[i-2];
        }
        System.out.println(Arrays.toString(dp));
        return dp[s.length() - 1];
    }

    // 不同路径
    public int uniquePaths(int m, int n) {
        // 状态表示：dp[i,j]表示走到当前位置的路径数量
        // 状态转移方程：dp[i,j] = dp[i-1,j] + dp[i,j-1];
        // 初始化：dp[0,0] = 1;(边缘化处理)
        // 填表顺序：从上到下，从左到右
        // 返回值：dp[m-1,n-1]
        int[][] dp = new int[m+1][n+1]; // 创建dp表的时候增加一行一列，避免繁琐的处理边界情况
        // 初始化
        dp[0][1] = 1;// 或dp[1][0] = 1
        // 填表
        for (int i = 0; i < m ; i ++) {
            for (int j = 0; j < n; j ++) {
                dp[i+1][j+1] = dp[i][j+1] + dp[i+1][j];
            }
        }
        return dp[m][n];
    }

    // 不同路径：多了一个障碍物
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        // 状态表示
        // 状态方程
        // 初始化
        // 填表顺序
        // 返回值
        // 以上同不同路径1
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;
        int[][] dp = new int[m+1][n+1];

        dp[0][1] = 1;

        for (int i = 0; i < m; i ++) {
            for (int j = 0; j < n; j ++) {
                if (obstacleGrid[i][j] == 1) {
                    dp[i+1][j+1] = 0;
                } else {
                    dp[i+1][j+1] = dp[i][j+1] + dp[i+1][j];
                }
            }
        }

        return dp[m][n];
    }

    // 珠宝的最高价值
    public int jewelleryValue(int[][] frame) {
        // 状态表示：dp[i][j]表示走到当前位置可以拿到的最大价值珠宝
        // 状态方程：dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + frame[i][j]
        // 初始化：不需要初始化
        // 填表顺序：从上到下，从左到右
        // 返回值：dp[m][n]

        int m = frame.length;
        int n = frame[0].length;
        int[][] dp = new int[m+1][n+1];

        // 初始化：不需要初始化
        for (int i = 0; i < m ; i ++) {
            for (int j = 0; j < n; j ++) {
                dp[i+1][j+1] = Math.max(dp[i+1][j],dp[i][j+1]) + frame[i][j];
            }
        }
        return dp[m][n];
    }

    // 下降路径最小和(初始化注意)
    public int minFallingPathSum(int[][] matrix) {
        // 状态表示：dp[i][j]表示当前位置最小和
        // 转移方程：dp[i][j] = min(Math.min(dp[i-1][j+1],dp[i-1][j]),dp[i-1][j-1])
        // 初始化:
        // 填表顺序：从左到右，从上到下
        // 返回值：
        int m = matrix.length;
        int n = matrix[0].length;

        int[][] dp = new int[m+1][n+2]; // 增加冗余，可以避免边界情况

        // 初始化要注意，两侧要初始化为Integer.MAX_INTEGER，不能是0
        for (int i = 0; i < m ; i ++) {
            dp[i+1][0] = Integer.MAX_VALUE;
            dp[i+1][n+1] = Integer.MAX_VALUE;
        }

        for (int i = 0; i < m; i ++) {
            for (int j = 0; j < n; j ++) {
                dp[i+1][j+1] = Math.min(Math.min(dp[i][j+1],dp[i][j]),dp[i][j+2]) + matrix[i][j];
            }
        }

        // 结果为最后一行最小值
        int min = Integer.MAX_VALUE;
        for (int i = 1; i <= n ; i ++) {
            if (dp[m][i] < min) min = dp[m][i];
        }

        return min;
    }

    // 最小路径和
    public int minPathSum(int[][] grid) {
        // 状态表示：dp[i][j] 表示当前和最小
        // 转移方程：dp[i][j] = Math.min(dp[i-1][j],dp[i][j-1]) + grid[i][j]
        // 初始化
        // 填表顺序：从上到下，从左到右
        // 返回值

        int m = grid.length;
        int n = grid[0].length;
        int[][] dp = new int[m+1][n+1]; // 需要初始化边缘为Integer.MAX_VALUE

        for (int i = 0; i <= n; i ++) dp[0][i] = Integer.MAX_VALUE;
        for (int i = 0; i <= m; i ++) dp[i][0] = Integer.MAX_VALUE;
        dp[0][1] = 0; // 第一个为0
        for (int i = 0; i < m; i ++) {
            for (int j = 0; j < n; j ++) {
                dp[i+1][j+1] = Math.min(dp[i][j+1],dp[i+1][j]) + grid[i][j];
            }
        }

        return dp[m][n];
    }

    // 地下城游戏
    public int calculateMinimumHP(int[][] dungeon) {
        // 状态表示：dp[i][j] 表示从当前位置走到末尾最小生命值
        // 转移方程：dp[i][j] = Math.min(dp[i][j+1],dp[i+1][j])- dungeon[i][j]
        // 初始化
        // 填表顺序：从下向上，从右到左
        // 返回值：dp[0][0]

        int m = dungeon.length;
        int n = dungeon[0].length;
        int[][] dp = new int[m+1][n+1];

        // 初始化
        for (int i = 0; i <= n; i ++) dp[m][i] = Integer.MAX_VALUE;
        for (int i = 0; i <= m; i ++) dp[i][n] = Integer.MAX_VALUE;

        dp[m][n-1] = 1; // 至少得有1滴血
        // 填表
        for (int i = m-1; i >= 0; i --) {
            for (int j = n-1; j >= 0; j --) {
                dp[i][j] = Math.min(dp[i+1][j],dp[i][j+1]) - dungeon[i][j];
                if (dp[i][j] <= 0) dp[i][j] = 1;
            }
        }

        return dp[0][0];
    }

    // 按摩师（打家劫舍1）
    public int massage(int[] nums) {
        // 状态表示：两种状态
        // f[i] 表示当前位置不预约的最长预约时间
        // g[i] 表示当前位置预约的最长预约时间
        // 状态转移方程：
        // f[i] = Math.max(f[i-1],g[i-1]) 当前位置不选，那么i-1位置选不选都可以
        // t[i] = f[i-1] + nums[i] 如果当前位置必选，那么i-1位置一定不选（相邻位置不能预约）
        // 初始化
        // 填表顺序
        // 返回值
        int len = nums.length;
        if (len == 0) {
            return 0;
        }

        int[] f = new int[len];
        int[] t = new int[len];

        // 初始化
        f[0] = 0;
        t[0] = nums[0];

        // 填表
        for(int i = 1; i < len; i ++) {
            f[i] = Math.max(f[i-1],t[i-1]);
            t[i] = nums[i] + f[i-1];
        }

        // 返回值
        return Math.max(f[len-1],t[len-1]);
    }

    // 打家劫舍2
    public int rob(int[] nums) {
        int n = nums.length;
        // 如果第一个位置tou，那么第二个位置和最后一个位置就不能偷，即2~n-2范围内最大值
        // 如果第一个位置不偷，那么就相当于区间 1~n-1范围内最大值
        return Math.max(nums[0] + rob1(nums,2,n-2),rob1(nums,1,n-1));
    }
    private int rob1(int[] nums,int left,int right) {
        if (left > right) {
            return 0;
        }
        int[] f = new int[nums.length];
        int[] t = new int[nums.length];

        t[left] = nums[left];
        f[left] = 0;
        for (int i = left+1; i <= right; i ++) {
            t[i] = nums[i] + f[i-1];
            f[i] = Math.max(f[i-1],t[i-1]);
        }
        return Math.max(f[right],t[right]);
    }

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        while (scan.hasNextInt()) {
            int a = scan.nextInt();
            int fifC = 0;
            int twtC = 0;
            int fiveC = 0;
            int oneC = 0;
            if (a/50 != 0) fifC = a/50;
            if (a%50/20 != 0) twtC = a%50/20;
            if (a%50%20/5 != 0) fiveC = a%50%20/5;
            if (a%50%20%5/1 != 0) oneC = a%50%20%5/1;

            System.out.println("找零--> 50元: "+fifC+"张.");
            System.out.println("找零--> 20元: "+twtC+"张.");
            System.out.println("找零--> 5 元: "+fiveC+"张.");
            System.out.println("找零--> 1 元: "+oneC+"张.");
        }
    }
}
